# -*- coding: utf-8 -*- 

import nltk,nltk.tokenize,xml.etree
import os,codecs,fnmatch,re,types, copy,shutil
import pickle
from sys import *
from pln_inco import graphviz,penn_treebank,stanford_parser,genia_tagger
from string import *
import pln_inco.bioscope.util
import time
import sqlite3
import random


def gen_text_files(bcp):
	""" Genera documentos solamente con el texto de las oraciones"""

	for docset in bcp.original_bioscope_corpus.getchildren(): # Recorro los document set (en este caso es uno solo)
		for doc in docset.getchildren(): # Recorro los documentos	
			# Identificador del documento
			docId=doc.getchildren()[0].text 
			print >> stderr, "Proceso archivo ",docId

			# Titulo
			title=doc.getchildren()[1].getchildren()[0]
			title_id=doc.getchildren()[1].getchildren()[0].get('id')

			# Ahora proceso las oraciones del texto
			doc_sentences=doc.getchildren()[2].getchildren()
			sentences=[(x,pln_inco.bioscope.util.bioscope_get_text(x)) for x in doc_sentences]

			# Genero el documento
			print >> stderr, "Genero documento txt...",docId
			fileName=os.path.join(bcp.txt_dir,'a'+docId+'.txt')
			f=codecs.open(fileName,'w', encoding='utf-8')
			f.write(pln_inco.bioscope.util.bioscope_get_text(title)+'\n')
			for (doc_sentence,sentence_text) in sentences:
				f.write(sentence_text+'\n')
			f.close()

				
def gen_bioscope_files(bcp):
	""" 
	Genera un archivo XML por cada documento del corpus bioscope 
	"""

	for docset in bcp.original_bioscope_corpus.getchildren(): # Recorro los document set (en este caso es uno solo)
		for doc in docset.getchildren(): # Recorro los documentos	
		# Identificador del documento
			docId=doc.getchildren()[0].text 
			print >> stderr, "Proceso archivo ",docId

			# Titulo
			title=doc.getchildren()[1].getchildren()[0]
			title_id=doc.getchildren()[1].getchildren()[0].get('id')

			# Ahora proceso las oraciones del texto
			doc_sentences=doc.getchildren()[2].getchildren()
			sentences=[(x,pln_inco.bioscope.util.bioscope_get_text(x)) for x in doc_sentences]


			# Generaciﺃ٣n de las marcas de bioscope
			print >> stderr, "Genero tags de bioscope...",docId
			fileName=os.path.join(bcp.bioscope_files_dir,'a'+docId+'.bioscope')
			f=open(fileName,'w')
			f.write('<?xml version="1.0" encoding="utf-8"?>')
			f.write('<Annotation>')
			f.write(strip(xml.etree.ElementTree.tostring(title,'utf-8'))+'\n')
			for (doc_sentence,sentence_text) in sentences:
				f.write(strip(xml.etree.ElementTree.tostring(doc_sentence,'utf-8'))+'\n')
			f.write('</Annotation>')
			f.close()


def create_single_text_file(bcp,pattern):
	""" 
	A partir de los archivos .txt del corpus que cumplen con pattern, genera un archivo único. Es para facilitar el proceso de anﺃ­lisis con el tagger de GENIA.
	"""

	output=''
	print >> stderr, "Genero archivo temporal para genia..."
	for fileName in os.listdir(bcp.txt_dir):
		if fnmatch.fnmatch(fileName,pattern):
			f=open(os.path.join(bcp.txt_dir,fileName),'r')
			output=output+'========='+fileName+'=========\n'+f.read()
			temp=open(bcp.genia_temp_file,"w")
			temp.write(output)
			temp.close()

def genia_tag(bcp):
	"""
	Procesa el archivo con los textos del corpus, y lo analiza con Genia
	"""
	# Primero tiene que copiar el archivo al home de Genia
	shutil.copy(bcp.genia_temp_file,bcp.genia_home)
	result=genia_tagger.tag(os.path.split(bcp.genia_temp_file)[1],bcp.genia_home)
	temp=open(bcp.genia_temp_results_file,"w")
	temp.write(result)
	temp.close()
	

def gen_genia_files(bcp):
	""" 
	Procesa el archivo resultado del anﺃ­lisis de Genia, y genera un archivo para cada documento y oración del corpus. 
	
	Lo generado por cada documento es un archivo en formato lema/POS, listo para ser proceado directamente por el Stanford Parser, corrigiendo algunos problemas en la salida 
	del tagger de GENIA y cambiando algunos formados para el PennTreeBank.
	
	También genera un archivo con los atributos de GENIA (ademﺃ­s del POS, NER y chunking), por cada oración, en un formato igual al que larga GENIA
	
	"""

	# Leo el archivo temporal
	f=open(bcp.genia_temp_results_file,'r')
	lineas=f.readlines()

	# Proceso las oraciones
	sentence_id=None
	s='' # Texto generado para la oración
	s_articulo='' # Texto generado para el artículo
	position=0
	# Indica si tengo que omitir procesar una línea porque la junté con la línea anterior
	saltar_lineas=0
	for l in lineas:
		#print >> stderr, "Proceso la linea ",l, "en la posicion ",position
		if saltar_lineas > 0:
			saltar_lineas = saltar_lineas-1
		elif l.startswith('========='):

			# Obtengo el id del artículo
			l=l.replace('=========','')
			index=l.find('\t')
			docId=l[0:index].replace('.txt','')

			# Obtengo el arbolito xml corrpondiente al artículo, a partir del .bioscope
			bioscope_doc=bcp.bioscope_files_corpus.xml(docId+'.bioscope')
			sentences=bioscope_doc.getchildren()

			sentence_pos=0
			s_articulo=''
			after_linea=True
		elif l=='\n' and not after_linea:
			# Estoy en un enter separador de oraciones
			# Genero el archivo correspondiente a la oración que venﺃﺝa procesando
			geniaFileName=docId+'.'+sentence_id+'.genia'
			print >> stderr, "Genero archivo ...", geniaFileName
			f=open(os.path.join(bcp.genia_files_dir,geniaFileName),'w+')
			f.write(s)
			f.close()

			# Inserto un enter en la salida del artículo
			s_articulo+= '\n'

			# Incremento el número de oración
			try:
				sentence_pos += 1
				sentence_id=sentences[sentence_pos].get('id')				
				s=''				
			except IndexError:
				# Como ya no quedan oraciones, genero el .genia del artículo
				geniaFileName=docId+'.genia'
				print >> stderr, "Genero archivo ...", geniaFileName
				f=open(os.path.join(bcp.genia_articles_dir,geniaFileName),'w+')
				f.write(s_articulo)
				f.close()
				s_articulo=''

		elif l=='\n':
			# Estoy en el primer enter, incremento el nﺃﻑmero de oración
			after_linea=False
			sentence_id=sentences[sentence_pos].get('id')				
			s=''				
		else:
			# Incremento la oración hasta el momento con la palabra
			#s += l
			# Para el caso de lo generado para el artículo, proceso la línea para que 
			# quede pronta para ser utilizada por el parser
			# El formato que genero es palabra/tag, con procesamiento para que quede como el penntreebank
			# Primero me quedo con las columnas 1 y 3
			(word,lemma,pos,chunk,ne)=split(l,'\t')
			# Quito el enter al ne
			ne=ne[0:len(ne)-1]

			#print >> stderr, "Position vale",position
			#print >> stderr, "Largo de lineas ",len(lineas)
			#print >> stderr, "split(lineas[position+1],'\t') ",split(lineas[position+1],'\t')
			#print >> stderr, "split(lineas[position+2],'\t') ",split(lineas[position+2],'\t')
			# Genia, en la ﺃﻑltima palabra de la oración, no tokeniza bien
			# Por lo que si la oración termina en un ., hay que generar dos tokens
			if pos=='.' and lemma<>'.' and word.endswith('.'):
				# Genia tiene un bug, que hace que en algunos casos si es la última palabra
				# No sﺃ٣lo la pega con el punto (como hace en general)
				# Sino que además le pone el tag '.'
				# Ver la oración S19.8, del documento a91187647

				# Lo que hago es separar en palabra y punto
				# Y ponerle a prepo el tag "NN" a la palabra que genia omitiﺃ٣ clasificar

				word=word[0:len(word)-1]
				lemma=word[0:len(word)-1]
				pos='NN'
				chunk='O'
				ne='O'

				s_articulo += '/'.join([word,pos])
				s_articulo += ' '
				s_articulo += '/'.join(['.','.'])
				s_articulo += ' '


				s += '\t'.join([word,lemma,pos,chunk,ne])
				s += '\n'
				s += '\t'.join(['.','.','.','O','O'])
				s += '\n'					
			elif word.endswith('.') and pos<>'.' and lineas[position+1]=='\n':
				# Si termina en punto, pero el lemma no es punto, y es la ﺃﻑltima palabra
				# Genia pegﺃ٣ la ﺃﻑltima palabra con el punto
				# por lo que los separo en dos
				lemma=lemma[0:len(lemma)-1]
				word=word[0:len(word)-1]

				s_articulo += '/'.join([word,pos])
				s_articulo += ' '
				s_articulo += '/'.join(['.','.'])
				s_articulo += ' '

				s += '\t'.join([word,lemma,pos,chunk,ne])
				s += '\n'
				s += '\t'.join(['.','.','.','O','O'])
				s += '\n'					


			elif pos=='CD' and position<=len(lineas)-3 and lineas[position+1]<>'\n' and lineas[position+2]<>'\n' and split(lineas[position+1],'\t')[2]==',' and split(lineas[position+2],'\t')[2]=='CD':
				# Si estoy en una situacion de numero,numero, genia lo separa errﺃ٣neamente
				# tengo que juntarlas
				# el pos, chunk y el ne quedan como el primero
				# tengo luego que saltarme las dos lineas siguientes
				siguiente_numero=split(lineas[position+2],'\t')[0]
				word=word+','+siguiente_numero
				lemma=lemma+','+siguiente_numero
				s_articulo +='/'.join([penn_treebank.ptb_conversion_word(word),penn_treebank.ptb_conversion_pos(pos)])
				s_articulo += ' '

				s += '\t'.join([penn_treebank.ptb_conversion_word(word),lemma,penn_treebank.ptb_conversion_pos(pos),chunk,ne])
				s +='\n'
				saltar_lineas=2					
			else:					
				# Caso general
				s_articulo +='/'.join([penn_treebank.ptb_conversion_word(word),penn_treebank.ptb_conversion_pos(pos)])
				s_articulo += ' '

				s += '\t'.join([penn_treebank.ptb_conversion_word(word),lemma,penn_treebank.ptb_conversion_pos(pos),chunk,ne])
				s +='\n'
		position=position+1


def gen_parsed_files(pattern,bcp,regenerate=True):
	"""
	Ejecuta el parser de stanford para los archivos con extensiﺃ٣n .genia que cumplan con el patrﺃ٣n. Guarda los resultados en archivos .parsed
	@arg pattern: patrﺃ٣n que indica los documentos a parsear
	@arg regenerate: indica si se deben regenerar archivos ya generados
	"""

	for fileName in os.listdir(bcp.genia_articles_dir):
		if fnmatch.fnmatch(fileName,pattern):
			
			print 'Pruebo si existe:',os.path.join(bcp.parsed_files_dir,fileName.replace('.genia','.parsed'))
			if not os.path.exists(os.path.join(bcp.parsed_files_dir,fileName.replace('.genia','.parsed'))) or regenerate:
				print>>stderr,  'Parseo...:'+fileName
				source=open(os.path.join(bcp.genia_articles_dir,fileName),'r')
				entrada=source.read()
				result=stanford_parser.parse(os.path.join(bcp.genia_articles_dir,fileName),bcp.parser_grammar_file)
				dest=open(os.path.join(bcp.parsed_files_dir,fileName.replace('.genia','.parsed')),'w')
				dest.write(result)
				source.close()
				dest.close()

def copy_genia_event_files(bcp):
	"""
	Copia los archivos de genia event correspondientes al corpus que estoy procesando. 
	Recorre el corpus y va copiando los documentos correspondientes, segﺃﻑn su nombre
	"""
	
	for docset in bcp.original_bioscope_corpus.getchildren(): # Recorro los document set (en este caso es uno solo)
		for doc in docset.getchildren(): # Recorro los documentos	
			# Identificador del documento
			docId=doc.getchildren()[0].text 
			print >> stderr, "Proceso archivo ",docId

			# En vez de copiarlo, lo abro y lo grabo.
			# Esto me permite ponerle el css en la copia
			try:
				source=open(os.path.join(bcp.genia_event_corpus_dir,docId+'.xml'),'r')
				dest=open(os.path.join(bcp.event_dir,'a'+docId+'.event.xml'),'w+')
				lineas=source.readlines()
				lineas.insert(1,'<?xml-stylesheet href="genia_event.css" type="text/css"?>')
				dest.writelines(lineas)
				source.close()
				dest.close()
			except IOError:
				print >>stderr, 'No existe el archivo '+ docId+'.xml'



def draw_sentences(bc,bcp,only_hedge_and_negation_sentences=True):
		""" 
		Dado un corpus, genera todas las imﺃ­genes de los ﺃ­rboles de anﺃ­lisis de sus oraciones
		@arg bc: Corpus
		@type bc: L{bioscope.BioscopeCorpus}
		@arg only_hedge_and_negation_sentences: indica si generar las imﺃ­genes para todas las oraciones, o sólo para aquellas que incluyen hedges o negación
		@type only_hedge_and_negation_sentences: Bool
		"""
		for (docId,d) in bc.documents.iteritems():
				print >> stderr, "Genero imﺃ­genes para el documento ",docId
				for (sentenceId,sentence) in d.sentences.iteritems():
					if sentence.data_loaded:
						if sentence.has_hedging() or sentence.has_negation() or not only_hedge_and_negation_sentences:
							print >> stderr, "Genero la imagen de la oracion ",sentenceId
							dot_spec=sentence.get_dot()
							salida_jpeg=graphviz.gen_jpeg_output(dot_spec)
							jpegFileName=docId+'.'+sentenceId+'.jpeg'
							f=open(os.path.join(bcp.image_files_dir,jpegFileName),"wb+")
							f.write(salida_jpeg)
							f.close()

def print_attribute_table(bc,bcp):
	""" 
	Genera los archivos con la tabulación de los atributos de cada oración de los documentos del corpus
	@arg bc: Corpus
	@type bc: L{bioscope.BioscopeCorpus}

	"""
	for (docId,d) in bc.documents.iteritems():
			print >> stderr, "Genero atributos para el documento ",docId	
			for (sentenceId,sentence) in d.sentences.iteritems():
				if sentence.data_loaded:
					s_table=sentence.get_att_table()
					tabFileName=docId+'.'+sentenceId+'.html'
					f=open(os.path.join(bcp.att_dir,tabFileName),'w+')
					f.write('<HTML><BODY><TABLE border=1>\n')
					content=''
					i=0
					for s in s_table:
						content +='<TR>'
						if i==0:
							for e in s:
								if type(e)==list:
									content +='<TH>'+'['+','.join(e)+']'+'</TH>'					
								else:
									content +='<TH>'+e+'</TH>'					
						else:
							for e in s:	
								if not e: e='None'
								
								if type(e)==list:
									content +='<TD>'+'['+','.join(e)+']'+'</TD>'													
								else:
									content +='<TD>'+e+'</TD>'
						content=content+'</TR>\n'
						i=i+1
					f.write(content)
					f.write('</TABLE></BODY></HTML>')
					f.close()


def save_basic_attributes(bc,dbname):
	"""
	Dado un corpus en memoria, persiste en la base de datos los atributos básicos. 
	La idea es que esto se corra sobre la tabla vacía.
	@arg bc: Corpus
	@type bc: L{bioscope.BioscopeCorpus}
	@arg dbname: nombre del archivo que tiene la base de datos
	@type dbname:C{string}
	
	"""

	t0=time.clock()
	conn= sqlite3.connect(dbname)	
	conn.text_factory = str
	
	c=conn.cursor()
	c.execute('delete from bioscope')
	for (docId,d) in bc.documents.iteritems():
			print >> stderr, "Genero atributos para el documento ",docId	
			for (sentenceId,sentence) in d.sentences.iteritems():
				token_num=0
				if sentence.data_loaded:
					s_table=sentence.get_basic_attributes()
					for s in s_table[1:]:
						token_num=token_num+1
						#s[0]=word
						#s[1]=lemma
						#s[2]=POS
						#s[3]=Chunk
						#s[4]=NER
						#s[5]= lista de HEDGE_CUES
						#s[6]= lista de NEG_CUES
						#s[7]= lista de SPEC_XCOPES
						
						
						# Proceso las hedge cues, genero un máximo de tres columnas para reflejar el anidamiento
						hedge_cue=['O']*3
						i=0
						for elem in s[5]:
							hedge_cue[i]=elem
							i=i+1
							if i==3:
								break
								
						if hedge_cue[0] != 'O':
							hc=hedge_cue[0]
						elif hedge_cue[1] != 'O':
							hc=hedge_cue[1]
						elif hedge_cue[2] != 'O':
							hc=hedge_cue[2]
						else:
							hc='O'	
						  
						
						# Proceso las marcas de scope
						# Genero un máximo de 3 columnas. Si no tienen nada, les pongo O
						hedge_xcope=['O']*3
						i=0
						for elem in s[7]:
							hedge_xcope[i]=elem
							i=i+1
							if i==3:
								break
						
						#print docId, sentenceId,token_num, s[0]
						c.execute("""insert into bioscope (document_id,sentence_id,token_num,word,lemma,POS,CHUNK,NER,hedge_cue,hedge_cue1, hedge_cue2, hedge_cue3,hedge_xcope1,hedge_xcope2,hedge_xcope3) 
						values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)""",
						(docId,sentenceId,token_num,s[0],s[1],s[2],s[3],s[4],hc,hedge_cue[0],hedge_cue[1],hedge_cue[2],hedge_xcope[0],hedge_xcope[1],hedge_xcope[2]))
	c.close()
	conn.commit()
	print 'Tiempo del proceso:', time.clock()-t0


def split_training_corpus(dbname):
	"""
	Separa la tabla bioscope en 80/20, manteniendo los atributos que tenga actualmente
	Reescribe las tablas bioscope80 y bioscope20.
	@arg dbname: nombre del archivo que tiene la base de datos
	@type dbname:C{string}
	"""
	
	#Abro la tabla bioscope en dbfile
	t0=time.clock()
	conn= sqlite3.connect(dbname)	
	conn.text_factory = str
	conn.row_factory=sqlite3.Row
	c=conn.cursor()
	c2=conn.cursor()

	# Dropeo las tablas bioscope80 y bioscope20
	# y las creo de nuevo, vacías
	try:
		c.execute('drop table bioscope80')
	except sqlite3.OperationalError:
		pass
		
	try:
		c.execute('drop table bioscope20')
	except sqlite3.OperationalError:
		pass

	c.execute('create table bioscope80 as select * from bioscope where 0=1')
	c.execute('create table bioscope20 as select * from bioscope where 0=1')
	conn.commit()
	
	
	# Recorro la tabla bioscope y separo el 80% de las oraciones entre entrenamiento y testeo
	c.execute('select document_id,sentence_id from bioscope group by sentence_id')
	for row in c:
		#Sorteo
		if random.random()<0.8:
			target_table='bioscope80';
		else:
			target_table='bioscope20';
		c2.execute('insert into '+target_table+' select * from bioscope where document_id=? and sentence_id=?',(row['document_id'],row['sentence_id']))
	conn.commit()
	c2.close()
	c.close()
			
def generate_scope_analysis_table(dbname,source_table,target_table, use_guessed_hedge_cue=False):
	"""
	Toma una tabla, recorre las oraciones y por cada instancia de HEDGE CUE que encuentra,
	genera una instancia de entrenamiento con la oración y la identificación del HC (además de los atributos que ya tenía).
	Convierte el scope al formato FOL
	@arg dbname: nombre del archivo que tiene la base de datos
	@type dbname:C{string}
	@arg source_table: nombre de la tabla origen (bioscope80)
	@type source_table:C{string}
	@arg target_table: nombre de la tabla destino (bioscope80_scope)
	@type target_table:C{string}
	@arg use_guessed_hedge_cue: indica si utilizar la hedge cue aprendida, por defecto es False
	@type C{Boolean}
	"""

	#Conexión a la base de datos
	t0=time.clock()
	conn= sqlite3.connect(dbname)	
	conn.text_factory = str
	conn.row_factory=sqlite3.Row
	c=conn.cursor()
	c2=conn.cursor()
	c3=conn.cursor()
	c4=conn.cursor()

	# Dropeo la tabla destino y la creo de nuevo, igual a la origen, vacía
	try:
		c.execute('drop table '+target_table)
	except sqlite3.OperationalError:
		pass

	# Creo una tabla igual a la origen, vacía
	print "Creo la tabla ", target_table
	c.execute('create table '+target_table+' as select * from '+source_table+' where 0=1')
	conn.commit()

	# Agrego el diferenciador de instancia, la columna para la hc, y la columna para el scope
	c.execute('alter table '+target_table+' add column hc_start integer');
	c.execute('alter table '+target_table+' add column hc_token string');
	c.execute('alter table '+target_table+' add column xcope string');
	c.execute('alter table '+target_table+' add column guessed_xcope string');
	

	conn.commit;

	# Recorro oración por oración y voy insertando
	# Antes armo la lista de columnas y signos de interrogación
	c.execute('select * from '+source_table+ ' limit 1')
	columnas=''
	interrogantes=''
	row=c.fetchone()
	cant_columnas=len(row.keys())+4
	for k in row.keys():
			columnas+=','+k
			interrogantes+=',?'
	columnas+=',hc_start,hc_token,xcope,guessed_xcope'
	columnas=columnas.lstrip(',')
	interrogantes=interrogantes.lstrip(',')
	interrogantes+=',?,?,?,?'
	
	
	# Ahora sí recorro e inserto
	#c.execute('select document_id,sentence_id from '+ source_table+' where sentence_id=\'S18.9\' group by document_id,sentence_id')
	c.execute('select document_id,sentence_id from '+ source_table+' group by document_id,sentence_id')


	if not  use_guessed_hedge_cue:
		hedge_cue_column='hedge_cue'
	else:
		hedge_cue_column='guessed_hedge_cue'

	for sentence in c:
		
		# Recorro la oración y obtengo los datos de cada hedge_cue diferente que encuentro
		cant_hc=0
		cues=[]		
		hedge_token=None
		hedge_nested_level=None
		hedge_pos=None
		c2.execute('select * from '+ source_table+' where document_id=? and sentence_id=?', (sentence['document_id'],sentence['sentence_id']))
		for row in c2:
			if sentence['sentence_id']=='S14.8':
				#print repr(row[hedge_cue_column])
				pass
			if str(row[hedge_cue_column])=='B-SPECCUE':
				#print 'ok'
				# Encontré una marca de especulación
				cant_hc=cant_hc+1
				hedge_token=row['word']
				hedge_pos=row['token_num']
				if row['hedge_cue1']==row[hedge_cue_column]:
					hedge_nested_level=1
				elif row['hedge_cue2']==row[hedge_cue_column]:
					hedge_nested_level=2
				elif row['hedge_cue3']==row[hedge_cue_column]:
						hedge_nested_level=3
				else:
						# Esto solamente ocurre si la cue es guessed
						hedge_nested_level=0
			elif str(row[hedge_cue_column])=='I-SPECCUE':
				# Sigue la última marca de especulación
				hedge_token=hedge_token+'_'+row['word']
			else:
					# Encontré una O, tengo que ver si estaba generando un token
					if hedge_token:
						cues.append((cant_hc,hedge_token,hedge_pos,hedge_nested_level))
						hedge_token=None
						hedge_nested_level=None
		
		# Recorro las marcas e identifico el comienzo y el fin del scope de cada una
		#print "Cantidad de marcas:",cant_hc
		for (instance_number,hedge_token,hedge_pos,hedge_nested_level) in cues:
			print "Posicion ",instance_number,":",hedge_pos,hedge_token," Anidamiento:",hedge_nested_level
			# Recorro la oración de nuevo, buscando cada scope
			c2.execute('select * from '+ source_table+' where document_id=? and sentence_id=?', (sentence['document_id'],sentence['sentence_id']))
			first=None
			last=None
			if hedge_nested_level != 0:
				hedge_xcope_column='hedge_xcope'+str(hedge_nested_level)
				for row in c2:
					if row[hedge_xcope_column]=='B-SPECXCOPE':
						if row['token_num']<=hedge_pos:
							first=row['token_num']
					elif row[hedge_xcope_column]=='I-SPECXCOPE':
							pass
					else:
						if first and row['token_num']>=hedge_pos:
							last=row['token_num']-1
							break
						else:
							first=None
				
			print "Comienzo de scope: ",first," Fin de scope ",last
			
			# Una vez identificado el scope, recorro todos los tokens y voy insertando en la tabla destino
			# Lo hago una vez por cada cue que tenga
			c2.execute('select * from '+ source_table+' where document_id=? and sentence_id=?', (sentence['document_id'],sentence['sentence_id']))
			for row in c2:
			
				# Copio las columnas originales
				valores=[]
				for k in row.keys():	
					valores.append(row[k])
				
				# Agrego la columna hc_start
				valores.append(hedge_pos)
				
				# Agrego la columna hc_token
				valores.append(hedge_token)
				
				#Determino el valor del scope, en formato FOL, y lo agrego
				if row['token_num']==first:
					xcope='F'
				elif row['token_num']==last:
					xcope='L'	
				else:
					xcope='O'
					
				valores.append(xcope)
				
				# Agrego el valor del guessed xcope por defecto, que es O
				valores.append('O')
				
	
				c3.execute('insert into '+ target_table+' ('+ columnas+') values ('+ interrogantes+')',valores)
			conn.commit()

def add_guessed_hedge_cue(dbname,tablename,test_filename):
	"""
	Agrega la columna guessed_hedge_cue para incorporar el resultado de una evaluación de hedge_cue
	que será utilizado como atributo para aprender el scope
	@arg dbname: nombre del archivo que tiene la base de datos
	@type dbname:C{string}
	@arg tablename: nombre de la tabla a la que se le agrega la columna
	@type tablename:C{string}
	@arg test_filename: archivo de testeo de donde obtengo el valor de la hedge cue aprendido
	@type test_filename:C{string}
	"""
	
	 
	# Inicializo la conección a la base de datos
	conn= sqlite3.connect(dbname)	
	conn.text_factory = str
	conn.row_factory=sqlite3.Row
	c=conn.cursor()


	# Agrego la columna guessed_hedge_cue y la inicializo en O
	try:	
		c.execute('alter table '+tablename+' add column guessed_hedge_cue')
	except sqlite3.OperationalError:
			pass	
	
	
	c.execute('update '+ tablename+ ' set guessed_hedge_cue=\'O\'')
	conn.commit()
	
	# Abreo el archivo y lo voy recorriendo
	# Asumo que en las primeras tres filas está el documento, la oraición y el token_num
	f=open(test_filename,'r')
	for line in f:
		if line !='\n':
			tokens=line.rstrip().split('\t')			
			document_id=tokens[0]
			sentence_id=tokens[1]
			token_num=tokens[2]					 
			if tokens[-1] != 'O':
				print "Actualizo ", document_id, sentence_id, token_num, tokens[-1]
				c.execute('update '+ tablename+' set guessed_hedge_cue=? where document_id=? and sentence_id=? and token_num=?',(tokens[-1],document_id,sentence_id,token_num))
	conn.commit()
	f.close()


def add_guessed_xcope(dbname,tablename,test_filename):
	"""
	Agrega la columna guessed_xcope para incorporar el resultado de una evaluación xcope
	@arg dbname: nombre del archivo que tiene la base de datos
	@type dbname:C{string}
	@arg tablename: nombre de la tabla a la que se le agrega la columna
	@type tablename:C{string}
	@arg test_filename: archivo de testeo de donde obtengo el valor del scope aprendido
	@type test_filename:C{string}
	"""
	
	 
	# Inicializo la conección a la base de datos
	conn= sqlite3.connect(dbname)	
	conn.text_factory = str
	conn.row_factory=sqlite3.Row
	c=conn.cursor()


	# Abreo el archivo y lo voy recorriendo
	# Asumo que en las primeras cuatro columnas está el documento, la oración, el token_num y el hc_start
	f=open(test_filename,'r')
	for line in f:
		if line !='\n':
			tokens=line.rstrip().split('\t')			
			document_id=tokens[0]
			sentence_id=tokens[1]
			token_num=tokens[2]	
			hc_start=tokens[3]				 
			if tokens[-1] != 'O':
				print "Actualizo ", document_id, sentence_id, token_num, hc_start, tokens[-1]
				c.execute('update '+ tablename+' set guessed_xcope=? where document_id=? and sentence_id=? and token_num=? and hc_start=?',(tokens[-1],document_id,sentence_id,token_num,hc_start))
	conn.commit()
	f.close()
		
			

def gen_conll_file(dbname,tablename,filename,xs,y, has_instances):
	""" 
	Genera el archivo para el entrenamiento/evaluación con CRF++, a partir de la tabla de bioscope que se le indique
	Este archivo está en formato CoNLL, tiene una línea por token, los atributos están
	separados por espacio, y el último es el que vamos a usar para clasificar. Las oraciones está­n separadas por líneas
	en blanco
	@arg dbname: nombre del archivo que tiene la base de datos
	@type dbname:C{string}
	@arg tablename: nombre de la tabla a partir de la cual generar el archivo
	@type tablename:C{string}
	@arg xs: lista de atributos a generar. Tienen que ser iguales a las columnas de la tabla de atributos de bioscope. No incluyen la clase a aprender.
	@type xs: List
	@arg y: Clase a aprender (es uno de los atributos)
	@type y:List
	@arg has_instances: indica si la tabla tiene varias instancias de la oración
	@type has_instances: Bool
	"""

	content=''	
	t0=time.clock()
	f=open(filename,'w+')
	conn= sqlite3.connect(dbname)	
	conn.text_factory = str
	conn.row_factory=sqlite3.Row
	c=conn.cursor()
	
	# Armo la lista separada por comas de los atributos
	# Por supuesto deben llamarse igual que las columnas de la tabla
	x2s=[]
	for x in xs:
		x2s.append(x)
	cabezal_select=','.join(xs)
	cabezal_select=cabezal_select+','+y+' '

	if has_instances:
		c.execute('select document_id,sentence_id,token_num,hc_start,'+cabezal_select+' from '+tablename+'  order by document_id,sentence_id,hc_start,token_num')
	else:
		c.execute('select document_id,sentence_id,token_num '+cabezal_select+' from '+tablename+'  order by document_id,sentence_id,token_num')
	
	prev_sentence_id='-1'	
	prev_instance=-1
	for row in c:
				if (prev_sentence_id != row['sentence_id']) or (has_instances and prev_instance != row['hc_start']):
					#Fin de la oración, dejo un espacio en blanco, excepto en la primera
					if prev_sentence_id != '-1':					
						content=content+'\n'
					prev_sentence_id = row['sentence_id']
					if has_instances: 
						prev_instance=row['hc_start']
				for k in row.keys():
						content=content+str(row[k])+'\t'
				#Borro el último tabulador
				content=rstrip(content)
				content=content+'\n'	
				f.write(content)
				content=''
	f.close()
	c.close()
	print 'Tiempo del proceso:', time.clock()-t0
